package dyyx.telnet;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.net.InetAddress;
import java.time.LocalTime;
import java.util.Date;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import dyyx.util.CommUtil;


@Sharable
public class TelnetServerHandlerUseThreadPool extends SimpleChannelInboundHandler<String> {
	
	
	public TelnetServerHandlerUseThreadPool(){
		System.out.println(this+" create at "+LocalTime.now());
	}

	private static final ThreadPoolExecutor bizPool = new ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS,
			new SynchronousQueue<Runnable>(),new DefaultThreadFactory("bizPool"));
	
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // Send greeting for a new connection.
        ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
        ctx.write("It is " + new Date() + " now.\r\n");
        ctx.flush();
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
       bizPool.submit(new Task(ctx,request) );
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
    
    private static long getSleepTime(String str){
    	if(str==null){
    		return 0;
    	}
    	String tmp = "sleep";
    	if(!str.startsWith(tmp)){
    		return 0;
    	}
    	final int LEN = tmp.length();
    	final int len = str.length();
    	if(len<=LEN){
    		return 0;
    	}
    	str = str.substring(LEN);
    	try{
    	    return Long.parseLong(str);
    	}catch(Throwable e){
    		return 0;
    	}
    }
    
	public final static void doSleep(long time){
		if(time<=0){
			return;
		}
		try{
			Thread.sleep(time);
		}catch(Throwable e){
			// 
		}
	}

    
    
	private static class Task implements Runnable {
		private final String request;
		final ChannelHandlerContext ctx;

		public Task(ChannelHandlerContext ctx, String request) {
			this.ctx = ctx;
			this.request = request;
		}

		public void run() {
			 // Generate and write a response.
	        String response;
	        boolean close = false;
	        
	        long sleepTime = getSleepTime(request);
	        System.out.println(LocalTime.now()+",recvmsg:"+request+",sleepTime="+sleepTime);
	        if(sleepTime>0){
	        	doSleep(sleepTime);
	        }
	        
	        
	        
	        if (request.isEmpty()) {
	            response = "Please type something.\r\n";
	        } else if ("bye".equals(request.toLowerCase())) {
	            response = "Have a good day!\r\n";
	            close = true;
	        } else {
	            response = "Did you say '" + request + "'?\r\n";
	        }

	        // We do not need to write a ChannelBuffer here.
	        // We know the encoder inserted at TelnetPipelineFactory will do the conversion.
	        // ChannelFuture future = ctx.write(response);
	        // 注意 一定要使用 writeAndFlush  否则客户端收不到消息 ！！！
	        ChannelFuture future = ctx.writeAndFlush(response);

	        System.out.println(LocalTime.now()+",write,msg="+response);

	        // Close the connection after sending 'Have a good day!'
	        // if the client has sent 'bye'.
	        if (close) {
	            future.addListener(ChannelFutureListener.CLOSE);
	        }

		}
	}
    
    
}
